#include "UdpSender.h"
#include <boost/asio.hpp>
#include <iostream>

UdpSender::UdpSender(const std::string &bindIP, const std::string &remoteIP, unsigned short port)
{
    // io_context 是 Boost.Asio 的事件处理器
    io_context_ = new boost::asio::io_context();
    socket_ = std::make_unique<boost::asio::ip::udp::socket>(*io_context_);
    socket_->open(boost::asio::ip::udp::v4()); // 打开 UDP 套接字
    if (bindIP.size() > 0)
    {
        // 尝试绑定到本地 IP 和端口
        boost::asio::ip::udp::endpoint local_endpoint(boost::asio::ip::make_address(bindIP), 0); // 端口号为 0，表示自动选择端口
        socket_->bind(local_endpoint);                                                           // 绑定到指定的本地 IP 和自动选择的端口
    }
    endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::make_address(remoteIP), port);

    // 检查 socket_ 是否成功打开
    if (!socket_->is_open())
    {
        std::cerr << "Socket is not open!" << std::endl;
    }
    else
    {
        // 启动事件循环
        // io_context.run() 会进入事件循环，不断监听和处理异步任务（例如数据接收、定时器、连接等）
        // 调用，否则异步操作不会生效
        // io_context_->run();  //没有事件时，它会阻塞等待。
    }
}

UdpSender::~UdpSender()
{
    // 析构函数，BOOST ASIO 会自动清理资源
    // 不需要显式释放 socket_，因为 std::unique_ptr 会自动调用析构函数释放内存
    if (io_context_ != nullptr)
    {
        io_context_->stop();
        delete io_context_; // 不会命中
    }
}

bool UdpSender::send(std::vector<uint8_t> buffer)
{
    if (!socket_)
    {
        std::cerr << "Socket is null!" << std::endl;
        return false;
    }

    try
    {
        if (!socket_->is_open())
        {
            std::cerr << "Socket is not open, cannot send data!" << std::endl;
            return false;
        }

        // 创建一个 Boost.Asio 的缓冲区对象
        boost::asio::buffer(buffer);

        // 发送数据到指定的端点
        socket_->send_to(boost::asio::buffer(buffer), endpoint_);
        // std::cout << "Sent " << buffer.size() << " bytes to " << endpoint_.address().to_string() << "::" << endpoint_.port() << std::endl;
        return true;
    }
    catch (const boost::system::system_error &e)
    {
        std::cerr << "Boost error during sending: " << e.what() << " (" << e.code() << ")" << std::endl;
    }
    catch (const std::exception &e)
    {
        std::cerr << "Standard error during sending: " << e.what() << std::endl;
    }
    return false;
}

bool UdpSender::dispose()
{
    return true;
}

// #include "UdpSender.h"
// #include <boost/asio.hpp>
// #include <iostream>

// UdpSender::UdpSender(const std::string &bindIP, const std::string &remoteIP, unsigned short port)
// {
//     // io_context 是 Boost.Asio 的事件处理器
//     io_context_ = new boost::asio::io_context();
//     socket_ = std::make_unique<boost::asio::ip::udp::socket>(*io_context_);
//     socket_->open(boost::asio::ip::udp::v4()); // 打开 UDP 套接字
//     if (bindIP.size() > 0)
//     {
//         // 尝试绑定到本地 IP 和端口
//         boost::asio::ip::udp::endpoint local_endpoint(boost::asio::ip::address::from_string(bindIP), 0); // 端口号为 0，表示自动选择端口
//         socket_->bind(local_endpoint);                                                                   // 绑定到指定的本地 IP 和自动选择的端口
//     }
//     endpoint_ = boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(remoteIP), port);

//     // 检查 socket_ 是否成功打开
//     if (!socket_->is_open())
//     {
//         std::cerr << "Socket is not open!" << std::endl;
//     }
//     else
//     {
//         // 启动事件循环
//         // io_context.run() 会进入事件循环，不断监听和处理异步任务（例如数据接收、定时器、连接等）
//         // 调用，否则异步操作不会生效
//         // io_context_->run();  //没有事件时，它会阻塞等待。
//     }
// }

// UdpSender::~UdpSender()
// {
//     // 析构函数，BOOST ASIO 会自动清理资源
//     // 不需要显式释放 socket_，因为 std::unique_ptr 会自动调用析构函数释放内存
//     if (io_context_ != nullptr)
//     {
//         io_context_->stop();
//         delete io_context_; // 不会命中
//     }
// }

// bool UdpSender::send(std::vector<uint8_t> buffer)
// {
//     if (!socket_)
//     {
//         std::cerr << "Socket is null!" << std::endl;
//         return false;
//     }

//     try
//     {
//         if (!socket_->is_open())
//         {
//             std::cerr << "Socket is not open, cannot send data!" << std::endl;
//             return false;
//         }

//         // 创建一个 Boost.Asio 的缓冲区对象
//         boost::asio::buffer(buffer);

//         // 发送数据到指定的端点
//         socket_->send_to(boost::asio::buffer(buffer), endpoint_);
//         // std::cout << "Sent " << buffer.size() << " bytes to " << endpoint_.address().to_string() << "::" << endpoint_.port() << std::endl;
//         return true;
//     }
//     catch (const boost::system::system_error &e)
//     {
//         std::cerr << "Boost error during sending: " << e.what() << " (" << e.code() << ")" << std::endl;
//     }
//     catch (const std::exception &e)
//     {
//         std::cerr << "Standard error during sending: " << e.what() << std::endl;
//     }
//     return false;
// }

// bool UdpSender::dispose()
// {
//     return true;
// }